/*******************************************************************************
 * Package: com.hngtrust.iir.report.service.impl
 * Type:    reportRightServiceImpl
 * Date:    2021/9/14 13:58
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.material.service.impl;

import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import com.hngtrust.framework.id.service.MyIdGenerator;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.elk.exception.ElkErrorType;
import com.hngtrust.iir.elk.exception.ElkException;
import com.hngtrust.iir.material.controller.dto.MaterialRightQueryVO;
import com.hngtrust.iir.material.controller.dto.MaterialRightUpadteVO;
import com.hngtrust.iir.material.controller.dto.MaterialRightUserOrDepartVO;
import com.hngtrust.iir.material.controller.dto.MaterialRightVO;
import com.hngtrust.iir.material.dto.MaterialRightDTO;
import com.hngtrust.iir.material.dto.MaterialRightUserOrDepartDTO;
import com.hngtrust.iir.material.entity.MaterialLog;
import com.hngtrust.iir.material.entity.MaterialRight;
import com.hngtrust.iir.material.service.MaterialLogService;
import com.hngtrust.iir.material.service.MaterialRightBacService;
import com.hngtrust.iir.material.service.MaterialRightService;
import com.hngtrust.iir.material.service.PrivateMaterialService;

import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.util.ElkUtils;
import com.tiger.util.MyHttpClient;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 内部资料-资料权限表
 *
 * @author Chaidd
 * @date 2021/11/09 3:58 下午
 */
@Service
@Slf4j
public class MaterialRightBacServiceImpl implements MaterialRightBacService {
    
    
    //文件路径
    @Value("${elk.search.url}")
    private String elkUrl;
    
    @Value(("${elk.search.indexname.means}"))
    private String fileName;
    
    @Autowired
    private MyIdGenerator myIdGenerator;

    @Autowired
    private MaterialRightService materialRightService;
    @Autowired
    private MaterialLogService materialLogService;
    @Autowired
    private PrivateMaterialService privateMaterialService;
    
    /**
     * 内部资料-新增收藏列表
     */
    @Override
    public void addRight(MaterialRightVO materialRightVO) {
        List<MaterialRight> materialRightList = new ArrayList<>();
        List<Long> userId = materialRightVO.getUserId();
        if (userId != null && userId.size() > 0){
            for (Long aLong : userId) {
                MaterialRight materialRight = new MaterialRight();
                materialRight.setId(myIdGenerator.nextId());
                materialRight.setCreateTime(new Date());
                User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
                materialRight.setCreateUserId(loginUser.getId());
                materialRight.setReportId(materialRightVO.getReportId());
                materialRight.setUserId(aLong);
                materialRightList.add(materialRight);
            }
        }
        if(materialRightList != null && materialRightList.size() >0) {
            materialRightService.addMaterial(materialRightList);
        }
    }
    
    /**
     * 内部资料-资料权限表列表
     * @param materialRightQueryVO
     * @return
     */
    @Override
    public List<MaterialRightDTO> listRight(MaterialRightQueryVO materialRightQueryVO) {
        MaterialRight materialRight = new MaterialRight();
        materialRight.setReportId(materialRightQueryVO.getReportId());
        List<MaterialRightDTO> list = materialRightService.queryReportRights(materialRight);
        return list;
    }
    
    /**
     * 内部资料-修改资料权限表
     * @param materialRightUpadteVO
     */
    @Override
    public void updateRight(MaterialRightUpadteVO materialRightUpadteVO) {
        Long reportId = materialRightUpadteVO.getReportId();
        //先根据资料id删除数据
        materialRightService.deleteRightByReportId(reportId);
        List<MaterialRight> materialRights = new ArrayList<>();
        List<Long> userId = materialRightUpadteVO.getUserId();
        //新增所有数据
        if (userId != null && userId.size() > 0) {
            for (Long aLong : userId) {
                MaterialRight materialRight = new MaterialRight();
                materialRight.setId(myIdGenerator.nextId());
                materialRight.setReportId(materialRightUpadteVO.getReportId());
                materialRight.setUserId(aLong);
                materialRight.setCreateTime(new Date());
                User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
                materialRight.setCreateUserId(loginUser.getId());
                materialRights.add(materialRight);
            }
            materialRightService.addRightByReportId(materialRights);
        }
        //修改主表权限标识字段，和下载权限设置字段
        materialRightService.updatePirvateReport(materialRightUpadteVO.getRightTag(),materialRightUpadteVO.getDwonTag(),materialRightUpadteVO.getReportId());
        
        //在内部资料操作日志表新建一条记录
        MaterialLog materialLog = new MaterialLog();
        materialLog.setId(myIdGenerator.nextId());
        //根据资料ID获取资料名称
        String reportTitle = privateMaterialService.queryReportTitleById(materialRightUpadteVO.getReportId());
        materialLog.setReportId(materialRightUpadteVO.getReportId());
        materialLog.setTitle(reportTitle);
        materialLog.setOptType("修改权限");
        materialLog.setCreateTime(new Date());
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        materialLog.setCreateUserId(loginUser.getId());
        materialLogService.add(materialLog);
        
        String url;
        if (StringUtil.isBlank(elkUrl) || StringUtil.isBlank(fileName)) {
            throw new ElkException(ElkErrorType.ELK_URL_INDEX_BLANK, elkUrl, fileName);
        }
        if (elkUrl.endsWith("/") || elkUrl.endsWith("\\")) {
            url = elkUrl + fileName + "/_update_by_query";
        } else {
            url = elkUrl + "/" + fileName + "/_update_by_query";
        }
        MaterialRight right = new MaterialRight();
        right.setReportId(materialRightUpadteVO.getReportId());
        List<Long> collect = materialRightService.queryList(right).stream().map(r -> r.getUserId())
                .collect(Collectors.toList());
        MyHttpClient client = new MyHttpClient();
        JSONConfig config = new JSONConfig();
        config.setOrder(true);
        JSONObject params = new JSONObject(config);
        JSONObject source = new JSONObject();
        source.put("source","ctx._source.iir['iir_tag_id'] = '"+collect+"';ctx._source.iir['iir_right_tag'] ='"+materialRightUpadteVO.getRightTag()+"';ctx._source.iir['iir_dow_tag'] ='"+materialRightUpadteVO.getDwonTag()+"'");
        JSONObject m = new JSONObject();
        JSONObject f= new JSONObject();
        f.put("iir.iir_mysql_id",materialRightUpadteVO.getReportId());
        m.put(ElkUtils.ELK_GRAMMAR_MATCH_PHRASE,f);
        params.put("script",source);
        params.put("query",m);
        
        log.info("修改参数{}",params.toString());
        client.postJson(url,params);
    }
    
    /**
     * 内部资料-权限部门或人员搜索
     * @param materialRightUserOrDepartVO
     */
    @Override
    public List<MaterialRightUserOrDepartDTO> queryUserOrDepartment(MaterialRightUserOrDepartVO materialRightUserOrDepartVO) {
        List<MaterialRightUserOrDepartDTO> materialRightUserOrDepartDTOS = new ArrayList<>();
        if(StringUtils.isNotBlank(materialRightUserOrDepartVO.getName())) {
            materialRightUserOrDepartDTOS = materialRightService.queryUserOrDepartment(materialRightUserOrDepartVO.getName());
        }
        if (materialRightUserOrDepartDTOS != null && materialRightUserOrDepartDTOS.size() >0){
            for (MaterialRightUserOrDepartDTO materialRightUserOrDepartDTO : materialRightUserOrDepartDTOS) {
                if(materialRightUserOrDepartDTO.getType() == 2){
                    //根据部门id查询下边是否有部门
                    List<Long> longs = new ArrayList<>();
                    List<Long> list = materialRightService.queryIdByParentId(materialRightUserOrDepartDTO.getDepartmentId());
                    if (list != null && list.size() > 0){
                        //部门下的用户
                        List<Long> list1 = materialRightService.queryUserIdByDeptId(materialRightUserOrDepartDTO.getDepartmentId());
                        if(list1 != null && list1.size() >0) {
                            longs.addAll(list1);
                        }
                        List<Long> recursion = recursion(list, longs);
                        Set<Long> set = new HashSet<>(recursion);
                        String join = StringUtils.join(set, ",");
                        materialRightUserOrDepartDTO.setUserId(join);
                    }else {
                        //最底层部门了，到用户表查询下边的用户
                        List<Long> list1 = materialRightService.queryUserIdByDeptId(materialRightUserOrDepartDTO.getDepartmentId());
                        if(list1 != null && list1.size() >0) {
                            String join = StringUtils.join(list1, ",");
                            materialRightUserOrDepartDTO.setUserId(join);
                        }else {
                            materialRightUserOrDepartDTO.setUserId(String.valueOf(materialRightUserOrDepartDTO.getDepartmentId()));
                        }
                    }
                }
            }
        }
        return materialRightUserOrDepartDTOS;
    }
    
    private List<Long> recursion(List<Long> list,List<Long> longs){
        if (list != null && list.size() > 0){
            for (Long aLong : list) {
                longs.add(aLong);
                //查询部门下的部门
                List<Long> longList = materialRightService.queryIdByParentId(aLong);
                if (longList != null && longList.size() > 0){
                    //查询部门下的人员
                    List<Long> list2 = materialRightService.queryUserIdByDeptId(aLong);
                    if (list2 != null && list2.size() > 0){
                        longs.addAll(list2);
                    }
                    recursion(longList,longs);
                }else {
                    List<Long> list1 = materialRightService.queryUserIdByDeptId(aLong);
                    if(list1 != null && list1.size() > 0) {
                        for (Long aLong1 : list1) {
                            longs.add(aLong1);
                        }
                    }else {
                        longs.add(aLong);
                    }
                }
            }
        }
        return longs;
    }
}




